package io.gitee.vexlife.snake.basic;

import java.util.LinkedList;

import io.gitee.vexlife.snake.GameController;

public class Snake {
	private LinkedList<Node> nodes;
	private Direction dir;

	public Snake(LinkedList<Node> nodes) {
		this.nodes = nodes;
		this.dir = Direction.RIGHT;
	}

	public LinkedList<Node> getNodes() {
		return this.nodes;
	}

	public void move(GameController gmctrl) {
		Node newNode, head = this.nodes.getLast();

		if (this.dir == null) {
			throw new NullPointerException("移动方向被设为了null！");
		}

		switch (this.dir) {
		case UP:
			newNode = new Node(head.getX(), head.getY() - 1);
			break;
		case LEFT:
			newNode = new Node(head.getX() - 1, head.getY());
			break;
		case RIGHT:
			newNode = new Node(head.getX() + 1, head.getY());
			break;
		case DOWN:
			newNode = new Node(head.getX(), head.getY() + 1);
			break;
		default:
			throw new IllegalArgumentException("无效的移动方向！");
		}

		if (gmctrl.getFood().getFoodNode().equals(newNode)) {
			this.nodes.add(newNode);
			gmctrl.getFood().genFood(gmctrl);
		} else {
			if (gmctrl.isEmpty(newNode) || this.getTail().equals(newNode)) {
				this.nodes.add(newNode);
				this.nodes.removeFirst();
			} else {
				gmctrl.gameOver();
				return;
			}
		}
	}

	public void turn(Direction dir) {
		switch (dir) {
		case LEFT:
			switch (this.dir) {
			case UP:
				this.dir = Direction.LEFT;
				break;
			case LEFT:
				this.dir = Direction.DOWN;
				break;
			case DOWN:
				this.dir = Direction.RIGHT;
				break;
			case RIGHT:
				this.dir = Direction.UP;
				break;
			}
			break;
		case RIGHT:
			switch (this.dir) {
			case UP:
				this.dir = Direction.RIGHT;
				break;
			case LEFT:
				this.dir = Direction.UP;
				break;
			case DOWN:
				this.dir = Direction.LEFT;
				break;
			case RIGHT:
				this.dir = Direction.DOWN;
				break;
			}
			break;
		default:
			throw new IllegalArgumentException("无效的移动方向！");
		}
	}

	public void setDirection(Direction dir) {
		this.dir = dir;
	}

	public Node getHead() {
		return this.nodes.getLast();
	}

	public Node getTail() {
		return this.nodes.getFirst();
	}

	public int getLength() {
		return this.getNodes().size();
	}

	public void setNodes(LinkedList nodes) {
		this.nodes=nodes;
	}

	public Direction getDirection() {
		return this.dir;
	}
}
